package com.markhsiu.nio.proxy;

import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

public class IOHandler {

	public void execute(ProxySession session, SelectionKey key) throws IOException {
		SocketChannel channel = (SocketChannel) key.channel();
		ProxyBuffer buffer = null;
		if (channel == session.frontChannel) {
			if (key.isReadable()) {
				System.out.println("frontChannel  read ========");
				buffer = session.backendBuffer;
			}
			if (key.isWritable()) {
				System.out.println("frontChannel  write ========");
				buffer = session.frontBuffer;
			}
		} else if (channel == session.backendChannel) {
			if (key.isReadable()) {
				System.out.println("backendChannel  read ========");
				buffer = session.frontBuffer;
			}
			if (key.isWritable()) {
				System.out.println("backendChannel  write ========");
				buffer = session.backendBuffer;
			}
		}

		if (buffer == null || channel == null) {
			throw new RuntimeException();
		}
		if (key.isReadable()) {
			read(buffer, channel);
		} else if (key.isWritable()) {
			write(buffer, channel);
		}
		register(session);
	}

	private void read(ProxyBuffer buffer, SocketChannel channel) throws IOException {
		buffer.read(channel);

	}

	private void write(ProxyBuffer buffer, SocketChannel channel) throws IOException {
		buffer.write(channel);
	}

	private void register(ProxySession session) throws ClosedChannelException {
		int clientOps = 0;
		if (session.backendBuffer.isFinishWrite()){
			clientOps |= SelectionKey.OP_READ;
		}
		if (session.frontBuffer.isFinishRead()){
			clientOps |= SelectionKey.OP_WRITE;
		}
		session.frontChannel.register(session.selector, clientOps, session);

		int serverOps = 0;
		if (session.frontBuffer.isFinishWrite()){
			serverOps |= SelectionKey.OP_READ;
		}
		if (session.backendBuffer.isFinishRead()){
			serverOps |= SelectionKey.OP_WRITE;
		}
		session.backendChannel.register(session.selector, serverOps, session);
	}
}
